package com.hzlj.position.locate.dao;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fz.common.base.converter.QueryWrapperConverterPlus;
import com.fz.common.base.core.JsonUtils;
import com.fz.common.base.core.date.DateUtils;
import com.fz.common.base.dto.PageParamDTO;
import com.fz.common.base.dto.QueryPageResultDTO;
import com.fz.common.base.dto.SortParamDTO;
import com.fz.stat.common.util.StatRestUtil;
import com.google.common.collect.Lists;
import com.hzlj.position.config.config.PositionConfig;
import com.hzlj.position.locate.common.common.ReadUpdateDTO;
import com.hzlj.position.locate.common.dto.reportCommon.ReportHandleDTO;
import com.hzlj.position.locate.common.dto.reportCommon.ReportInspectionStatDTO;
import com.hzlj.position.locate.common.dto.reportInspection.ReportInspectionNoticeDTO;
import com.hzlj.position.locate.common.dto.reportInspection.ReportInspectionQueryParamDTO;
import com.hzlj.position.locate.common.dto.reportInspection.ReportInspectionWithJzJbxxDTO;
import com.hzlj.position.locate.common.enums.ReportStatus;
import com.hzlj.position.locate.common.model.ReportInspection;
import com.hzlj.position.locate.mapper.ReportInspectionMapper;
import com.hzlj.sqjz.config.common.dto.common.handle.HandleCommonQueryResultDTO;
import com.hzlj.sqjz.config.common.enums.HandleStatus;
import com.hzlj.sqjz.jz.common.constant.JzJoin;
import com.hzlj.sqjz.jz.common.model.JzJbxx;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 通信联络核查-核查(ReportInspection)表操作类
 *
 * @author lifh
 * @date 2023-07-21 14:20:19
 */
@Repository
public class ReportInspectionDao extends ServiceImpl<ReportInspectionMapper, ReportInspection> {
    @Resource
    private ReportInspectionMapper reportInspectionMapper;
    @Resource
    private PositionConfig positionConfig;


    public ReportInspection getReportInspection(String id, Date now) {
        LambdaQueryWrapper<ReportInspection> queryWrapper = new QueryWrapper<ReportInspection>().lambda()
                .eq(ReportInspection::getBelongDay, DateUtil.beginOfDay(now))
                .eq(ReportInspection::getId, id);
        return this.getOne(queryWrapper);
    }

    public ReportInspectionNoticeDTO getReportInspection4Notice(String id, Date now) {
        return QueryWrapperConverterPlus.of(reportInspectionMapper)
                .selectOne(ReportInspectionNoticeDTO.class, null, null, q -> q
                        .eq(ReportInspection::getBelongDay, DateUtil.beginOfDay(now))
                        .eq(ReportInspection::getId, id)
                );
    }


    public void updateNotice(String id,
                             Date belongDay,
                             Boolean notice,
                             String noticeFailMsg) {
        LambdaUpdateWrapper<ReportInspection> updateWrapper = new UpdateWrapper<ReportInspection>().lambda()
                .set(ReportInspection::getNotice, notice)
                .set(ReportInspection::getNoticeFailMsg, noticeFailMsg)
                .eq(ReportInspection::getId, id)
                .eq(ReportInspection::getBelongDay, belongDay);
        this.update(updateWrapper);
    }


    public void updateByInspections(List<ReportInspection> inspections) {
        if (CollectionUtil.isEmpty(inspections)) {
            return;
        }
        for (ReportInspection inspection : inspections) {
            LambdaUpdateWrapper<ReportInspection> updateWrapper = new UpdateWrapper<ReportInspection>().lambda()
                    .eq(ReportInspection::getId, inspection.getId())
                    .eq(ReportInspection::getBelongDay, inspection.getBelongDay());
            this.update(inspection, updateWrapper);
        }
    }

    public void delete(String jzId, Date now) {
        LambdaUpdateWrapper<ReportInspection> deleteWrapper = new UpdateWrapper<ReportInspection>().lambda()
                .eq(ReportInspection::getJzId, jzId)
                .eq(ReportInspection::getBelongDay, now);
        this.remove(deleteWrapper);
    }

    public void deleteByJgCodeWithUnSuccess(String reportType,
                                            String jgCode,
                                            Date startDay,
                                            Date endDay) {
        ReportInspectionQueryParamDTO params = new ReportInspectionQueryParamDTO();
        params.setJzzt(null)
                .setReportType(reportType)
                .setBeginBelongDay(DateUtil.beginOfDay(startDay))
                .setEndBelongDay(DateUtil.endOfDay(endDay))
                .setReportStatuses(Lists.newArrayList(ReportStatus._WAIT.getStatus(), ReportStatus._NEVER.getStatus()));
        params.setJgCode(jgCode);
        //查询需要删除的记录
        List<String> ids = QueryWrapperConverterPlus.of(reportInspectionMapper)
                .innerJoin(JzJbxx.class, JzJoin.jz(ReportInspection::getJzId))
                .list(String.class, params, q -> q.select(ReportInspection::getId));
        if (ObjectUtil.isEmpty(ids)) {
            return;
        }
        //删除
        this.remove(new UpdateWrapper<ReportInspection>().lambda()
                .in(ReportInspection::getId, ids)
                .ge(ReportInspection::getBelongDay, DateUtil.beginOfDay(startDay))
                .le(ReportInspection::getBelongDay, DateUtil.endOfDay(endDay))
        );
    }


    /**
     * 查询列表：不分页
     */
    public List<ReportInspectionWithJzJbxxDTO> listReportInspection(ReportInspectionQueryParamDTO dto) {
        return query(dto).list(ReportInspectionWithJzJbxxDTO.class, dto, sortParam(dto), q -> {
            q.le(Boolean.TRUE.equals(dto.getReachSpotCheckTime()), ReportInspection::getSpotCheckTime, new Date());
        });
    }

    /**
     * 查询列表：分页
     */
    public QueryPageResultDTO<ReportInspectionWithJzJbxxDTO> pageReportInspection(ReportInspectionQueryParamDTO dto, PageParamDTO page) {
        page.setSortFns(sortParam(dto).getSortFns());

        return query(dto).page(ReportInspectionWithJzJbxxDTO.class, dto, page, q -> {
            q.le(Boolean.TRUE.equals(dto.getReachSpotCheckTime()), ReportInspection::getSpotCheckTime, new Date());
        });
    }

    private QueryWrapperConverterPlus<ReportInspection> query(ReportInspectionQueryParamDTO dto) {
        if (dto.getBelongDay() != null) {
            dto.setBeginBelongDay(DateUtil.beginOfDay(dto.getBelongDay()));
            dto.setEndBelongDay(DateUtil.endOfDay(dto.getBelongDay()));
            dto.setBelongDay(null);
        }
        return QueryWrapperConverterPlus.of(reportInspectionMapper)
                .innerJoin(JzJbxx.class, JzJoin.jz(ReportInspection::getJzId));

    }

    public ReportInspectionStatDTO statByReportStatus(String jgCode, String reportType, Date day) {
        String belongDay = DateUtils.formatShortDate(day);
        ReportInspectionStatDTO result = StatRestUtil.map(positionConfig.getStatService().getUrl(),
                "sqlIds=1067&belongDay=" + belongDay + "&jgCode=" + jgCode + "&reportType=" + reportType + "&jzId=",
                ReportInspectionStatDTO.class);
        if (result == null) {
            return new ReportInspectionStatDTO();
        }
        return result;

    }


    private SortParamDTO sortParam(ReportInspectionQueryParamDTO param) {
        if (Boolean.TRUE.equals(param.getSortBySpotCheckTime())) {
            return SortParamDTO.of(false, ReportInspection::getSpotCheckTime)
                    .and(false, ReportInspection::getId);
        } else {
            return SortParamDTO.of(false, ReportInspection::getReportStatus)
                    .and(false, ReportInspection::getReportTime)
                    .and(false, ReportInspection::getId);
        }

    }


    public void handle(ReportHandleDTO dto) {
        Pair<Date, Date> dateDatePair = dto.minMaxBelongDay();
        LambdaUpdateWrapper<ReportInspection> updateWrapper = new UpdateWrapper<ReportInspection>().lambda()
                .set(ReportInspection::getHandleStatus, dto.getHandleStatus())
                .set(ReportInspection::getHandleTime, dto.getHandleTime())
                .set(ObjectUtil.isNotEmpty(dto.getHandleExt()), ReportInspection::getHandleExt, JsonUtils.obj2json(dto.getHandleExt()))
                .in(ReportInspection::getId, dto.ids())
                .ge(ReportInspection::getBelongDay, dateDatePair.getKey())
                .le(ReportInspection::getBelongDay, dateDatePair.getValue());
        this.update(updateWrapper);
    }

    public void updateHandleStatus(String id,
                                   Date belongDay,
                                   HandleStatus handleStatus) {
        LambdaUpdateWrapper<ReportInspection> updateWrapper = new UpdateWrapper<ReportInspection>().lambda()
                .set(ReportInspection::getHandleStatus, handleStatus.getStatus())
                .eq(ReportInspection::getId, id)
                .eq(ReportInspection::getBelongDay, belongDay);
        this.update(updateWrapper);
    }

    public void read(ReadUpdateDTO dto) {
        LambdaUpdateWrapper<ReportInspection> updateWrapper = new UpdateWrapper<ReportInspection>().lambda()
                .set(ReportInspection::getRead, true)
                .set(ReportInspection::getReadTime, dto.getReadTime())
                .eq(ReportInspection::getId, dto.getId())
                .ge(ReportInspection::getBelongDay, DateUtil.beginOfDay(dto.getRecordTime()))
                .le(ReportInspection::getBelongDay, DateUtil.beginOfDay(dto.getRecordTime()));
        this.update(updateWrapper);
    }

    public HandleCommonQueryResultDTO getHandleResult(String id, Date belongDay) {
        return QueryWrapperConverterPlus.of(reportInspectionMapper)
                .selectOne(HandleCommonQueryResultDTO.class, null, null, q -> {
                    q.eq(ReportInspection::getId, id)
                            .eq(ReportInspection::getBelongDay, belongDay);
                });
    }

}

